﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using SharedGenomics.TextMining;

namespace SharedGenomics.Workbench.Views.WindowsForms
{
    //TODO: ideally this class would be refactored to remove all the logic but it's not too bad since most of it is encapsulated in the PublicationTitleMiner
    public partial class TextMinedPublicationView : View, ITextMinedPublicationsView
    {
        private PublicationTitleMiner _miner;
        Color[] _quartileColours = new Color[] { Color.Blue, Color.Green, Color.Orange, Color.Red };

        public TextMinedPublicationView()
        {
            InitializeComponent();
        }

        private void Form_Load(object sender, EventArgs e)
        {
            int yPos = 10;

            foreach (PublicationMining pm in this._miner.RankedMinedPublications)
            {
                MinedPublicationDisplayControl dc = new MinedPublicationDisplayControl(pm, this._quartileColours);
                dc.Location = new Point(10, yPos);
                dc.SizeChanged += new EventHandler(DisplayControl_SizeChanged);

                this.plPublications.Controls.Add(dc);

                yPos += dc.Height + 5;
            }
        }

        private void DisplayControl_SizeChanged(object sender, EventArgs e)
        {
            int maxWidth = -1;
            int yLoc = 0;

            //find the widest control in the collection and resize all other controls to be the same width
            foreach (Control c in this.plPublications.Controls)
            {
                if (c.Width > maxWidth)
                    maxWidth = c.Width;
            }

            Point autoScrollPosition;

            foreach (Control c in this.plPublications.Controls)
            {
                //get the autoscroll position of the panel - this messes up the positioning of all its child controls on the form
                autoScrollPosition = this.plPublications.AutoScrollPosition;

                c.Width = maxWidth;

                //update the location of the control on the panel - a correction must be made for the autoscroll position of the panel - I don't really know 
                //why...
                c.Location = new Point(0 + autoScrollPosition.X, yLoc + autoScrollPosition.Y);

                yLoc += c.Height + 5;
            }
        }

        private void plKey_Paint(object sender, PaintEventArgs e)
        {
            Size quartileRectSize = new Size(15, 15);
            Point currentRectLocation = new Point(5, 5);
            int fillRectWidth = 2;

            Size fillRectSize = new Size(quartileRectSize.Width - fillRectWidth, quartileRectSize.Height - fillRectWidth);

            Brush fillBrush;
            Pen outlinePen = new Pen(Color.Black, fillRectWidth);

            string keyDescription;
            Brush keyDescriptionBrush = new SolidBrush(this.plKey.ForeColor);
            Font keyDescriptionFont = this.plKey.Font;
            int keyDescriptionWidth;
            StringFormat keyDescriptionFormat = new StringFormat();
            keyDescriptionFormat.Alignment = StringAlignment.Center;

            Graphics g = e.Graphics;

            for (int i = this._quartileColours.Length - 1; i >= 0; i--)
            {
                //draw rectangle outline
                g.DrawRectangle(outlinePen, new Rectangle(currentRectLocation, quartileRectSize));

                //draw a filled rectangle inside the outline
                fillBrush = new SolidBrush(this._quartileColours[i]);
                Point fillRectLocation = new Point(currentRectLocation.X + fillRectWidth - 1, currentRectLocation.Y + fillRectWidth - 1);
                g.FillRectangle(fillBrush, new Rectangle(fillRectLocation, fillRectSize));

                //draw text to describe the key meaning
                keyDescription = String.Format("Quartile {0}", (i + 1));

                //calculate the bounding rectangle for the string - rectangle is the same height as the 'quartile rectangle' (i.e. the height of the colour 
                //block outline) and is as wide as the string and there is a gap of 2 pixels from the right hand edge of the key colour block
                keyDescriptionWidth = (int)Math.Ceiling(g.MeasureString(keyDescription, keyDescriptionFont).Width);
                int textXPos = currentRectLocation.X + quartileRectSize.Width + 2;
                Rectangle textBoundingRectangle = new Rectangle(textXPos, currentRectLocation.Y, keyDescriptionWidth, quartileRectSize.Height);

                //draw text within bounding rectangle and align text vertically in the centre
                g.DrawString(keyDescription, keyDescriptionFont, keyDescriptionBrush, textBoundingRectangle, keyDescriptionFormat);

                currentRectLocation.X = (textXPos + keyDescriptionWidth + 5);
            }

            //shrink containing panel and groupbox width to tightly fit the key contents
            this.plKey.Width = currentRectLocation.X;
            this.gpbKey.Width = (2 * this.plKey.Location.X) + this.plKey.Width;
        }

        public PublicationTitleMiner TitleMiner
        {
            set { this._miner = value; }
        }

        public override string Title
        {
            get { return "Publications"; }
        }
    }
}
